package com.tools.utils;

import org.apache.commons.lang.StringUtils;

import java.io.BufferedReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static java.util.regex.Pattern.compile;

/**
 * StringUtil
 *
 * @author  < a href=" ">ZhangYang</ a>
 * @version v1.0.01
 * @date    2018-08-22 15:45:47
 */
public class StringUtil {

  /**
   * @param obj
   *
   * @return
   */
  public static String asString(Object obj) {
    return obj != null ? obj.toString() : "";
  }

  /**
   * @param obj
   *
   * @return
   */
  public static boolean isEmpty(Object obj) {
    return (obj == null || obj.toString().length() == 0);
  }

  /**
   * @param srcString
   * @param paddedLength
   * @param paddingString
   *
   * @return
   */
  public static String lpad(String srcString, int paddedLength, String paddingString) {
    int srcLength = asString(srcString).length();
    int padStrLength = asString(paddingString).length();

    if (srcLength < paddedLength && !isEmpty(paddingString) && !isEmpty(paddingString)) {
      int leftLength = paddedLength - srcLength;
      int cnt = leftLength / padStrLength + (leftLength % padStrLength > 0 ? 1 : 0);
      StringBuffer sb = new StringBuffer(padStrLength * cnt);
      for (int i = 0; i < cnt; i++) {
        sb.append(paddingString);
      }
      return sb.substring(0, leftLength) + srcString;
    } else if (srcLength > paddedLength) {
      return srcString.substring(0, paddedLength);
    } else {
      return srcString;
    }
  }

  /**
   * @param srcString
   * @param paddedLength
   * @param paddingString
   *
   * @return
   */
  public static String rpad(String srcString, int paddedLength, String paddingString) {
    int srcLength = asString(srcString).length();
    int padStrLength = asString(paddingString).length();

    if (srcLength < paddedLength && !isEmpty(paddingString) && !isEmpty(paddingString)) {
      int leftLength = paddedLength - srcLength;
      int cnt = leftLength / padStrLength + (leftLength % padStrLength > 0 ? 1 : 0);
      StringBuffer sb = new StringBuffer(padStrLength * cnt);
      for (int i = 0; i < cnt; i++) {
        sb.append(paddingString);
      }
      return srcString + sb.substring(0, leftLength);
    } else if (srcLength > paddedLength) {
      return srcString.substring(0, paddedLength);
    } else {
      return srcString;
    }
  }

  /**
   * @param list
   * @param joinStr
   *
   * @return
   */
  public static String join(String[] list, String joinStr) {
    StringBuffer s = new StringBuffer();
    for (int i = 0; list != null && i < list.length; i++) {
      if ((i + 1) == list.length) {
        s.append(list[i]);
      } else {
        s.append(list[i]).append(joinStr);
      }
    }
    return s.toString();
  }

  /**
   * firstCharLowerCase
   *
   * @param s String
   *
   * @return String
   */
  public static String firstCharLowerCase(String s) {
    if (s == null || "".equals(s)) {
      return ("");
    }
    return s.substring(0, 1).toLowerCase() + s.substring(1);
  }

  /**
   * firstCharUpperCase
   *
   * @param s String
   *
   * @return String
   */
  public static String firstCharUpperCase(String s) {
    if (s == null || "".equals(s)) {
      return ("");
    }
    return s.substring(0, 1).toUpperCase() + s.substring(1);
  }

  /**
   * @return
   */
  public static String toBeanPatternStr(String src) {
    String dist = src.toLowerCase();
    Pattern pattern = compile("_([a-z0-9])");
    Matcher matcher = pattern.matcher(dist);
    while (matcher.find()) {
      dist = dist.replaceFirst(matcher.group(0), matcher.group(1).toUpperCase());
    }
    return dist;
  }

  /**
   * @param src
   *
   * @return
   */
  public static String toJSLineSeparateStr(String src) {
    if (src == null) {
      return "";
    }
    String dist = src;
    dist = dist.replaceAll("\r\n", "\\\\n");
    dist = dist.replaceAll("\r", "\\\\n");
    dist = dist.replaceAll("\n", "\\\\n");
    return dist;
  }

  /**
   * @param input
   * @param tail
   * @param length
   *
   * @return
   */
  public static String getShorterString(String input, String tail, int length) {
    tail = isEmpty(tail) ? tail : "";
    StringBuffer buffer = new StringBuffer(512);
    try {
      int len = input.getBytes("GBK").length;
      if (len > length) {
        int ln = 0;
        for (int i = 0; ln < length; i++) {
          String temp = input.substring(i, i + 1);
          if (temp.getBytes("GBK").length == 2) {
            ln += 2;
          } else {
            ln++;
          }

          if (ln <= length) {
            buffer.append(temp);
          }
        }
      } else {
        return input;
      }
      buffer.append(tail);
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return buffer.toString();
  }

  /**
   * @return
   */
  public static String getBytesString(String input, String code) {
    try {
      byte[] b = input.getBytes(code);
      return Arrays.toString(b);
    } catch (UnsupportedEncodingException e) {
      return String.valueOf(code.hashCode());
    }
  }

  /**
   * @param clob
   *
   * @return
   */
  public static String getStringFromClob(java.sql.Clob clob) {
    String result = "";
    try {
      if (clob == null) {
        return null;
      }
      Reader reader = clob.getCharacterStream();
      BufferedReader br = new BufferedReader(reader);
      String line = br.readLine();
      StringBuffer sb = new StringBuffer(1024);
      while (line != null) {
        sb.append(line);
        line = br.readLine();
      }
      result = sb.toString();
    } catch (Exception ex) {

    }
    return result;
  }

  /**
   * cust_code='111,222,333'
   * to
   * (cust_code='111' or cust_code='222' or cust_code='333')
   *
   * @param srcString
   * @param token
   * @param columnName
   * @param isVarchar
   *
   * @return
   */
  public static String parseToSqlOr(String srcString, String token, String columnName, boolean isVarchar) {
    String[] srcArray = StringUtils.split(srcString, token);
    StringBuffer sql = new StringBuffer();
    sql.append(" ( ");
    for (int i = 0; i < srcArray.length; i++) {
      Pattern p = compile("\\s*|\t|\r|\n");
      Matcher m = p.matcher(srcArray[i]);
      String srcArrayTrim = m.replaceAll("");
      if (isVarchar) {
        sql.append(columnName + "='" + srcArrayTrim + "' ");
      } else {
        sql.append(columnName + "=" + srcArrayTrim + " ");
      }
      if (i < srcArray.length - 1) {
        sql.append(" or ");
      }
    }
    sql.append(" ) ");
    return sql.toString();
  }

  /**
   * @param srcString
   * @param columnName
   *
   * @return
   */
  public static String parseToSqlOr(String srcString, String columnName) {
    return parseToSqlOr(srcString, ",", columnName, true);
  }

  /**
   * 去掉下划线并将字符串转换成帕斯卡命名规范
   *
   * @param str
   *
   * @return
   */
  public static String unlineToPascal(String str) {
    if (str != null) {
      if (str.indexOf("_") == -1) {
        return fristToUpCase(str);
      }
      StringBuilder result = new StringBuilder();
      String[] temp = str.split("_");
      for (int i = 0; i < temp.length; i++) {
        if ( StringUtils.isEmpty(temp[i])) {
          continue;
        }
        result.append(fristToUpCaseLaterToLoCase(temp[i]));
      }
      return result.toString();
    }

    return str;
  }

  /**
   * 去掉下划线并将字符串转换成驼峰命名规范
   *
   * @param str
   *
   * @return
   */
  public static String unlineToCamel(String str) {
    if (str != null) {
      if (str.indexOf("_") == -1) {
        return fristToLoCase(str);
      }
      StringBuilder result = new StringBuilder();
      String[] temp = str.split("_");
      boolean falg = false;
      for (int i = 0; i < temp.length; i++) {
        if (StringUtils.isEmpty(temp[i])) {
          continue;
        }
        if (falg == false) {
          falg = true;
          result.append(temp[i].toLowerCase());
        } else {
          result.append(fristToUpCaseLaterToLoCase(temp[i]));
        }
      }
      return result.toString();
    }

    return str;
  }

  /**
   * 将字符串首字母大写其后小写
   *
   * @param str
   *
   * @return
   */
  public static String fristToUpCaseLaterToLoCase(String str) {
    if (str != null && str.length() > 0) {
      str = (str.substring(0, 1).toUpperCase()) + (str.substring(1).toLowerCase());
    }
    return str;
  }

  /**
   * 将字符串首字母小写其后大写
   *
   * @param str
   *
   * @return
   */
  public static String fristToLoCaseLaterToUpCase(String str) {
    if (str != null && str.length() > 0) {
      str = (str.substring(0, 1).toLowerCase()) + (str.substring(1).toUpperCase());

    }
    return str;
  }

  /**
   * 将字符串首字母大写
   *
   * @param str
   *
   * @return
   */
  public static String fristToUpCase(String str) {
    if (str != null && str.length() > 0) {
      str = str.substring(0, 1).toUpperCase() + str.substring(1);
    }
    return str;
  }

  /**
   * 将字符串首字母小写
   *
   * @param str
   *
   * @return
   */
  public static String fristToLoCase(String str) {
    if (str != null && str.length() > 0) {
      str = str.substring(0, 1).toLowerCase() + str.substring(1);
    }
    return str;
  }

  /**
   * 检查字符串里面是否包含指定字符,包含返回true
   *
   * @param regex 指定字符
   * @param str 字符串
   *
   * @return
   */
  public static boolean indexOf(String regex, String... str) {
    if (str == null) {
      return false;
    }
    for (String temp : str) {
      if (temp.indexOf(regex) == -1) {
        return false;
      }
    }
    return true;
  }

  /**
   * 如果jdk大于1.8可以直接使用String.join<br>
   * 将字符串中间以separator连接起来<br>
   * 示例:magre(".","1","2","3") 结果:"1.2.3"
   *
   * @param separator
   * @param str
   *
   * @return
   */
  @Deprecated()
  public static String magre(String separator, String... str) {
    StringBuffer result = null;
    for (String temp : str) {
      if (result == null) {
        result = new StringBuffer(temp);
      }
      result.append("," + temp);
    }
    return result.toString();
  }

  /**
   * 将字符串str中带有集合中rep[0]的字符串,代替为rep[1]的中的字符串
   *
   * @param str
   * @param rep
   *
   * @return
   */
  public static String replace(String str, List<String[]> rep) {
    for (String[] item : rep) {
      if (item[1] == null) {
        item[1] = "";
      }
      str = str.replace(item[0], item[1]);
    }
    return str;
  }

  /**
   * 创建字符串数组
   *
   * @param str
   *
   * @return
   */
  public static String[] asStrArray(String... str) {
    return str;
  }

  /**
   * 判断字符串是否为null或者空,如果是返回true
   *
   * @param str
   *
   * @return
   */
  public static boolean isNullOrEmpty(String str) {
    if (str == null || "".equals(str.trim())) {
      return true;
    }
    return false;
  }

  /**
   * 判断字符串是否为null或者空,如果是返回true
   *
   * @param str
   *
   * @return
   */
  public static boolean isNullOrEmpty(String... str) {
    for (int i = 0; i < str.length; i++) {
      if (str[i] == null || "".equals(str[i].trim())) {
        return true;
      }
    }
    return false;
  }

  /**
   * 正则表达式匹配两个指定字符串中间的内容
   *
   * @param soap
   *
   * @return
   */
  public static List<String> getSubUtil(String soap, String rgex) {
    List<String> list = new ArrayList<String>();
    Pattern pattern = Pattern.compile(rgex);
    Matcher m = pattern.matcher(soap);
    while (m.find()) {
      int i = 1;
      list.add(m.group(i));
      i++;
    }
    return list;
  }

  /**
   * 返回单个字符串，若匹配到多个的话就返回第一个，方法与getSubUtil一样
   *
   * @param soap
   * @param rgex
   *
   * @return
   */
  public static String getSubUtilSimple(String soap, String rgex) {
    Pattern pattern = Pattern.compile(rgex);
    Matcher m = pattern.matcher(soap);
    while (m.find()) {
      return m.group(1);
    }
    return "";
  }

}
